package org.paybiz.core.payplatform.bill99.service;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.security.KeyStore;
import java.util.Properties;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.paybiz.core.payplatform.bill99.constant.Bill99Constant;
import org.paybiz.core.payplatform.bill99.entity.Ivr;
import org.paybiz.core.payplatform.bill99.entity.MerchantInfo;
import org.paybiz.core.payplatform.bill99.entity.TransInfo;
import org.paybiz.core.payplatform.bill99.util.Base64Binrary;
import org.paybiz.core.payplatform.bill99.util.MyX509TrustManager;
import org.paybiz.core.payplatform.bill99.util.PropFile;
import org.paybiz.util.DynamicConfig;

/**
 * 语音支付数据发送处理类
 * @author nassir wen
 * @data 2012-5-15 下午01:44:19
 * @version V2.5
 * @Company: MSD.
 * @Copyright Copyright (c) 2012
 */
public class PostTr1ProcessorHandler{
    
    private final static Log logger = LogFactory.getLog(PostTr1ProcessorHandler.class);
    
    private static MerchantInfo merchantInfo = null;
    
    private static String BILL99_IVR_RETURNURL = "";
    
    static {
        try {
            Properties p = PropFile.getProps(Bill99Constant.IVR_PROP_PATH);
            merchantInfo = new MerchantInfo();
            merchantInfo.setCertPass(p.getProperty("certPassword"));
            merchantInfo.setCertPath(Bill99Constant.IVR_JKS_PATH);
            merchantInfo.setMerchantId(Bill99Constant.BILL99_IVR_MERID);
            merchantInfo.setPassword(p.getProperty("merchantLoginKey"));
            merchantInfo.setTimeOut(p.getProperty("timeout"));
            merchantInfo.setDomainName(p.getProperty("domainName"));
            merchantInfo.setSslPort(p.getProperty("sslPort"));
            BILL99_IVR_RETURNURL = DynamicConfig.getInstance().getValue(Bill99Constant.BILL99_IVR_RETURNURL);
        } catch (Exception e) {
            logger.error("读取配置文件出错!",e);
        }
    }
    /**
     * 报文发送
     * @param reqXml
     * @param postUrl 报文发送地址
     * @return 
     * @throws Exception
     */
	public static InputStream post(String reqXml,String postUrl) throws Exception {
		// 验证密钥源
		File certFile = new File(merchantInfo.getCertPath());
		KeyStore ks = KeyStore.getInstance("JKS");
		ks.load(new FileInputStream(certFile), merchantInfo.getCertPass().toCharArray());
		KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
		kmf.init(ks, merchantInfo.getCertPass().toCharArray());

		// 同位体验证信任决策源
		TrustManager[] tm = { new MyX509TrustManager() };

		// 初始化安全套接字
		SSLContext sslContext = SSLContext.getInstance("SSL");
		sslContext.init(kmf.getKeyManagers(), tm, null);

		SSLSocketFactory factory = sslContext.getSocketFactory();
		//"https://mas.99bill.com/cnp/purchase" port:443
		URL url = new URL(merchantInfo.getBaseUrl() + postUrl);
		HttpsURLConnection urlc = (HttpsURLConnection) url.openConnection();
		urlc.setSSLSocketFactory(factory);
		urlc.setDoOutput(true);
		urlc.setDoInput(true);
		urlc.setReadTimeout(merchantInfo.getTimeOut() * 1000);

		String authString = merchantInfo.getMerchantId() + ":" + merchantInfo.getPassword();
		
		String auth = "Basic " + Base64Binrary.encodeBase64Binrary(authString.getBytes());
		
		urlc.setRequestProperty("Authorization", auth);

		OutputStream out = urlc.getOutputStream();
		out.write(reqXml.getBytes("UTF-8"));
		
		out.flush();
		out.close();

		return urlc.getInputStream();
	}
	
	/**
	 * 构造TR1发送报文
	 * @param ivr
	 * @return
	 */
	public static String createSendTR1XML(Ivr ivr,TransInfo transInfo){
	    StringBuffer reqXml = null;
	    reqXml = appendParam(reqXml, "version", ivr.getVersion(),transInfo);
	    reqXml = appendParam(reqXml, "txnType", ivr.getTxnType(),transInfo);
	    reqXml = appendParam(reqXml, "interactiveStatus", ivr.getInteractiveStatus(),transInfo);
	    reqXml = appendParam(reqXml, "cardNo", ivr.getCardNo(),transInfo);
	    reqXml = appendParam(reqXml, "amount", ivr.getAmount(),transInfo);
	    reqXml = appendParam(reqXml, "merchantId", merchantInfo.getMerchantId(),transInfo);
	    reqXml = appendParam(reqXml, "settleMerchantId", ivr.getSettleMerchantId(),transInfo);
	    reqXml = appendParam(reqXml, "terminalId", ivr.getTerminalId(),transInfo);
	    reqXml = appendParam(reqXml, "entryTime", ivr.getEntryTime(),transInfo);
	    reqXml = appendParam(reqXml, "externalRefNumber", ivr.getExternalRefNumber(),transInfo);
	    reqXml = appendParam(reqXml, "customerId", ivr.getCustomerId(),transInfo);
	    reqXml = appendParam(reqXml, "cardHolderName", ivr.getCardHolderName(),transInfo);
	    reqXml = appendParam(reqXml, "cardHolderId", ivr.getCardHolderId(),transInfo);
	    reqXml = appendParam(reqXml, "issuerCountry", ivr.getIssuerCountry(),transInfo);
	    reqXml = appendParam(reqXml, "spFlag", ivr.getSpFlag(),transInfo);
	    String cellphone = ivr.getCellphone();
	    if (cellphone != null && !"".equals(cellphone)) {
	        reqXml
	        .append("<extMap><extDate><key>cellphone</key><value>")
	        .append(cellphone)
	        .append("</value></extDate></extMap>");
	    }
	    reqXml.append("<tr3Url>").append(BILL99_IVR_RETURNURL).append("</tr3Url>");
	    //结束xml
	    reqXml = appendParam(reqXml, "", "",transInfo);
	    return reqXml.toString();
	}
	
	/**
     * 改方法用于正常的交易拼接XML，返回StringBuffer sb：初始StringBuffer paraName：XML中的标签名
     * paraValue：XML中标签对应的值
     **/
    private static StringBuffer appendParam(StringBuffer reqXml,
            String paraName, String paraValue,TransInfo transInfo) {
        // 如果输入的值为null,那么使它们的值为""
        if (paraValue == null) {
            paraValue = "";
        } 
        // 下面开始组合XML
        if (reqXml == null) {
            reqXml = new StringBuffer();
            String contentXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><MasMessage xmlns=\"http://www.99bill.com/mas_cnp_merchant_interface\">";
            reqXml.append(contentXML).append("<").append(paraName).append(">")
                    .append(paraValue).append("</").append(paraName)
                    .append(">").append("<")
                    .append(transInfo.getRecordeText_1()).append(">");
        } else if ((!"".equals(paraName)) && (!"".equals(paraValue))) {
            reqXml.append("<").append(paraName).append(">").append(paraValue)
                    .append("</").append(paraName).append(">");
        } else if (("".equals(paraName)) && ("".equals(paraValue))) {
            reqXml.append("</").append(transInfo.getRecordeText_1())
                    .append(">").append("</MasMessage>");
        }

        return reqXml;
    }
}
